package juego;

import java.util.ArrayList;
import java.util.Iterator;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class TorpedoRastreador extends Torpedo{
	
	//atributos de clase
	private static int rapidezDiagonal = 3;
	
	//constructor
	public TorpedoRastreador(Coordenada ubicacion){
		super(ubicacion);
	};
	
	//pre: recibe como parametros las listas de moviles y de botines.
	//post: actualiza las listas y retorna los puntos que deban computarse
	@Override
	public int vivir(ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		int puntaje = 0;
		//movimiento
		this.movimientoPropio(listaDeMoviles);
		if (this.EstaFueraDelEscenario(this.ubicacion)){
			this.destruirse(listaDeMoviles);
		}else{
		//impacto
		puntaje = this.impactar(listaDeMoviles,listaDeBotines);}
		return puntaje;
	};
	
	
	protected void movimientoPropio(ArrayList<Movil> listaDeMoviles){
		Movil enemigo = this.buscarPrimerEnemigo(listaDeMoviles);
		if (enemigo == null){
			this.moverSinEnemigos();
		}//si hay al menos un enemigo
		else{
			//busca al mas cercano
			enemigo = buscarEnemigoMasCercano(enemigo,listaDeMoviles);
			this.moverHaciaEnemigo(enemigo);
			
		}
	
	
	}
	
	private void moverHaciaEnemigo(Movil enemigo) {
		Coordenada ubicacionEnemigo = enemigo.getCentro();
		int diferenciaEnX = (ubicacionEnemigo.obtenerCoordenadaX() - this.ubicacion.obtenerCoordenadaX());
		int diferenciaEnY = (ubicacionEnemigo.obtenerCoordenadaY() - this.ubicacion.obtenerCoordenadaY());
		Coordenada vectorDistancia = new Coordenada(diferenciaEnX,diferenciaEnY);
		//si el modulo del vectorDistancia es mayor que la velocidad
		if (vectorDistancia.getModulo() > this.velocidad()){
			//lo normalizo
			vectorDistancia.normalizar();
			//y lo multiplico por la velocidad
			int movimientoHorizontal = vectorDistancia.obtenerCoordenadaX();
			int movimientoVertical = vectorDistancia.obtenerCoordenadaY();
			this.moverVelocidadAdecuada(movimientoHorizontal,movimientoVertical);
			//this.ubicacion.moverEnXY(movimientoHorizontal, movimientoVertical);
		}
		//si el enemigo esta mas cerca que la velocidad igualo su posicion
		else{
			this.ubicacion.moverEnXY(diferenciaEnX, diferenciaEnY);
		}
		
	}

	
	//este metodo se encarga de adecuar el movimiento a la velocidad
	private void moverVelocidadAdecuada(int movimientoHorizontal, int movimientoVertical) {
		//(0,1)->(0,10)  (0,-1)->(0,-10) (0,0)->(0,0) 
		if (movimientoHorizontal == 0){
			movimientoVertical *= this.velocidad();
		}
		else{
			//(1,0)->(10,0)  (-1,0)->(-10,0) (0,0)->(0,0) 
			if (movimientoVertical == 0){
				movimientoHorizontal *= this.velocidad();
			}
			else{
				//(1,1)->(3,3)  (-1,1)->(-3,3) (1,-1)->(3,-3) (-1,-1)->(-3,-3)
				movimientoHorizontal *= rapidezDiagonal;
				movimientoVertical *= rapidezDiagonal;
			}
		}
		this.ubicacion.moverEnXY(movimientoHorizontal, movimientoVertical);
				
	}

	private Movil buscarEnemigoMasCercano(Movil enemigo, ArrayList<Movil> listaDeMoviles) {
		int distanciaEnemigo = this.ubicacion.distancia(enemigo.verUbicacion());
		Iterator<Movil> iterador = listaDeMoviles.iterator();
		while (iterador.hasNext()){
			Movil movil = iterador.next();
			boolean somosEnemigos = (this.esLeal != movil.verLealtad());
			if (somosEnemigos & !movil.esProyectil()){
				Coordenada ubicacionDelMovil = movil.verUbicacion();
				int distanciaMovil = this.ubicacion.distancia(ubicacionDelMovil);
				//si el enemigo actual esta mas cerca que el enemigo anterior
				if(distanciaMovil < distanciaEnemigo){
					enemigo = movil;
			        distanciaEnemigo = distanciaMovil;
            	}
			}
		}
		return enemigo;
	}

	//se mueve en vertical
	private void moverSinEnemigos(){
		int movimiento = this.velocidad();
		if (this.esLeal){
		   movimiento = movimiento*(-1);
		}
		ubicacion.moverEnY(movimiento);
	}
	
	//busca al primer enemigo que aparece en la lista. si no hay enemigos
	//retorna null
	private Movil buscarPrimerEnemigo(ArrayList<Movil> listaDeMoviles){
		Movil enemigo = null;
		Iterator<Movil> iterador = listaDeMoviles.iterator();
		//busco el primer enemigo de la lista
		while ((enemigo == null) && (iterador.hasNext())) {
			Movil movil = iterador.next();
			boolean lealtadDeMovil = movil.verLealtad();
			if (this.verLealtad() != lealtadDeMovil) {
				//que la lealtad se distinta me asegura que no esta comparando consigo
				//mismo
				boolean esProyectil = movil.esProyectil();
				if (!esProyectil) {
					enemigo = movil;
				}
			}
		}
		return enemigo;
	}
	
	

	
	public Element getElement(Document doc) {
		Element proyectil = doc.createElement("TorpedoRastreador");
		
		this.persistirProyectil(doc, proyectil);
		
		return proyectil;
	}
	

	
	

	public static TorpedoRastreador fromElement(Element element) {
		TorpedoRastreador proyectil = new TorpedoRastreador(new Coordenada(-1,-1));
		
		Proyectil.recuperarProyectil(element,proyectil);
			
		return proyectil;
	}
	
	
	
	
	


};
